package com.yh.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 用来复制属性值;相当于cn.hutool.core.bean.BeanUtil.copyProperties
 * @author 湛锋
 *
 */
public class BeanUtil {
	
	private BeanUtil() {}
	
	/**
	 * 
	 * @param sourceBean 被复制的对象；已知
	 * @param targetBean 复制到的对象；目标
	 * @param ignoreProperties 哪些属性不被复制
	 */
	public static void copy(Object sourceBean,Object targetBean,String...ignoreProperties) {
		Set<String> ignorePropertiesSet = new HashSet<>();
		if(ignoreProperties!=null){
			java.util.Collections.addAll(ignorePropertiesSet, ignoreProperties);
		}
		Class<?> sourceClass = sourceBean.getClass();
		Class<?> targetClass = targetBean.getClass();
		try {
			BeanInfo sourceInfo = Introspector.getBeanInfo(sourceClass);
			PropertyDescriptor[] propertys = sourceInfo.getPropertyDescriptors();
			Map<String, PropertyDescriptor> map = new HashMap<String, PropertyDescriptor>();
			for(PropertyDescriptor p : propertys) {
				map.put(p.getName(), p);
			}
			BeanInfo targetInfo = Introspector.getBeanInfo(targetClass);
			propertys = targetInfo.getPropertyDescriptors();
			for(PropertyDescriptor p : propertys) {
				if(p.getWriteMethod()==null) {//如果目标bean的属性没有setter，跳过，进入下一个属性
					continue;
				}
				if(ignorePropertiesSet.contains(p.getName())) {//如果目标bean的属性在忽略的属性中，跳过
					continue;
				}
				PropertyDescriptor sourceProperty = map.get(p.getName());
				if(sourceProperty == null || sourceProperty.getReadMethod() == null) {//如果原对象没有对应的getter方法，跳过
					continue;
				}
				//以上条件都成立后，将原对象要复制的属性的值进行获取
				Object obj = sourceProperty.getReadMethod().invoke(sourceBean);
				//将该值复制给目标对象
				if(obj != null) {
					p.getWriteMethod().invoke(targetBean, obj);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
